package com.genexususa.eo.google.connection;

import com.genexususa.eo.google.exceptions.ConnectionException;
import com.google.api.ads.adwords.axis.factory.AdWordsServices;
import com.google.api.ads.adwords.axis.v201406.ch.CustomerSyncServiceInterface;
import com.google.api.ads.adwords.axis.v201406.cm.*;
import com.google.api.ads.adwords.axis.v201406.mcm.ManagedCustomerServiceInterface;
import com.google.api.ads.adwords.lib.client.AdWordsSession;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Properties;

public class ServiceFactory {
    private static ServiceFactory Instance = new ServiceFactory();

    private CampaignServiceInterface _campaignService;

    private BudgetServiceInterface _budgetService;

    private AdGroupServiceInterface _adGroupService;

    private ExperimentServiceInterface _experimentService;

    private AdGroupCriterionServiceInterface _adGroupCriterionService;

    private CampaignCriterionServiceInterface _campaignCriterionService;

    private AdGroupAdServiceInterface _adGroupAdService;

   // private AdExtensionOverrideServiceInterface _adExtensionOverrideService;

    private CampaignAdExtensionServiceInterface _campaignAdExtensionService;

    private GeoLocationServiceInterface _geoLocationService;

    private ConversionTrackerServiceInterface _conversionTrackerService;

    private ManagedCustomerServiceInterface _managedCustomerService;

    private ReportDefinitionServiceInterface _reportDefinitionService;

    private FeedServiceInterface _feedServiceInterface;

    private FeedItemServiceInterface _feedItemServiceInterface;

    private FeedMappingServiceInterface _feedMappingServiceInterface;

    private CampaignFeedServiceInterface _campaignFeedServiceInterface;

    private BiddingStrategyServiceInterface _biddingStrategyServiceInterface;

    private LocationCriterionServiceInterface _locationCriterionService;

    private CustomerSyncServiceInterface _customerSyncService;

    private String clientLoginToken = "";

    private AdWordsSession _session;

    public static ServiceFactory getInstance() {
        return Instance;
    }

    private ServiceFactory() {
    }

    private void getSession(String clientId) throws IOException, ConnectionException {
        Properties properties = new Properties();
        properties.load(ServiceFactory.class.getResourceAsStream("/eo.properties"));
        int retries = Integer.valueOf(properties.getProperty("noReponseRetries"));
        int timeBetweenRetries = Integer.valueOf(properties.getProperty("noResponseTBR"));

        SessionController sc = SessionController.getInstance();

        int i=0;
        boolean connectionException = true;
        while (i<=retries && connectionException) {
            try {
                _session = sc.GetSession(clientId);
                connectionException = false;
            } catch (ConnectionException e) {
                System.out.println("There was no response");
                if (i < retries) {
                    try {
                        Thread.sleep(timeBetweenRetries);
                    } catch (InterruptedException e1) {
                        throw e;
                    }
                    System.out.println("Retrying.....");
                }
                i++;
            }
        }
        if (connectionException) {
            throw new ConnectionException();
        }
    }

    public CampaignServiceInterface GetCampaignService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);

        _session.setPartialFailure(false);

        AdWordsServices adWordsServices = new AdWordsServices();

        _campaignService = adWordsServices.get(_session, CampaignServiceInterface.class);

        return _campaignService;
    }

    public BudgetServiceInterface GetBudgetService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);

        _session.setPartialFailure(false);

        AdWordsServices adWordsServices = new AdWordsServices();
        _budgetService = adWordsServices.get(_session, BudgetServiceInterface.class);

        return _budgetService;
    }

    public AdGroupServiceInterface GetAdGroupService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _adGroupService = adWordsServices.get(_session, AdGroupServiceInterface.class);


        return _adGroupService;
    }

    public ExperimentServiceInterface GetExperimentService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _experimentService = adWordsServices.get(_session, ExperimentServiceInterface.class);


        return _experimentService;
    }

    public AdGroupCriterionServiceInterface GetAdGroupCriterionService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _adGroupCriterionService = adWordsServices.get(_session, AdGroupCriterionServiceInterface.class);

        return _adGroupCriterionService;

    }

    public CampaignCriterionServiceInterface GetCampaignCriterionService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _campaignCriterionService = adWordsServices.get(_session, CampaignCriterionServiceInterface.class);

        return _campaignCriterionService;
    }

    public AdGroupAdServiceInterface GetAdGroupAdService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _adGroupAdService = adWordsServices.get(_session, AdGroupAdServiceInterface.class);

        return _adGroupAdService;

    }

   /* public AdExtensionOverrideServiceInterface GetAdExtensionOverrideService(String clientId) {

        SessionController sc = SessionController.getInstance();

        _session = sc.GetSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _adExtensionOverrideService = adWordsServices.get(_session, AdExtensionOverrideServiceInterface.class);

        return _adExtensionOverrideService;

    } */

    public CampaignAdExtensionServiceInterface GetCampaignAdExtensionService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _campaignAdExtensionService = adWordsServices.get(_session, CampaignAdExtensionServiceInterface.class);

        return _campaignAdExtensionService;

    }

    public ReportDefinitionServiceInterface GetReportDefinitionService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(false);
        AdWordsServices adWordsServices = new AdWordsServices();

        _reportDefinitionService = adWordsServices.get(_session, ReportDefinitionServiceInterface.class);

        return _reportDefinitionService;


    }

    public GeoLocationServiceInterface GetGeoLocationService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(false);
        AdWordsServices adWordsServices = new AdWordsServices();

        _geoLocationService = adWordsServices.get(_session, GeoLocationServiceInterface.class);

        return _geoLocationService;

    }

    public ConversionTrackerServiceInterface GetConversionTrackerService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(false);
        AdWordsServices adWordsServices = new AdWordsServices();

        _conversionTrackerService = adWordsServices.get(_session, ConversionTrackerServiceInterface.class);

        return _conversionTrackerService;
    }

    public ManagedCustomerServiceInterface GetManagedCustomerService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(false);
        AdWordsServices adWordsServices = new AdWordsServices();

        _managedCustomerService = adWordsServices.get(_session, ManagedCustomerServiceInterface.class);

        return _managedCustomerService;
    }


    public FeedServiceInterface GetFeedServiceInterface(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        AdWordsServices adWordsServices = new AdWordsServices();
        _feedServiceInterface = adWordsServices.get(_session, FeedServiceInterface.class);
        return _feedServiceInterface;
    }

    public FeedItemServiceInterface GetFeedItemServiceInterface(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        AdWordsServices adWordsServices = new AdWordsServices();
        _feedItemServiceInterface = adWordsServices.get(_session, FeedItemServiceInterface.class);
        return _feedItemServiceInterface;

    }

    public FeedMappingServiceInterface GetFeedMappingServiceInterface(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        AdWordsServices adWordsServices = new AdWordsServices();
        _feedMappingServiceInterface = adWordsServices.get(_session, FeedMappingServiceInterface.class);
        return _feedMappingServiceInterface;
    }

    public CampaignFeedServiceInterface GetCampaignFeedServiceInterface(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        AdWordsServices adWordsServices = new AdWordsServices();
        _campaignFeedServiceInterface = adWordsServices.get(_session, CampaignFeedServiceInterface.class);
        return _campaignFeedServiceInterface;
    }

    public BiddingStrategyServiceInterface GetBiddingStrategyServiceInterface(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        AdWordsServices adWordsServices = new AdWordsServices();
        _biddingStrategyServiceInterface = adWordsServices.get(_session, BiddingStrategyServiceInterface.class);
        return _biddingStrategyServiceInterface;
    }

    public LocationCriterionServiceInterface GetLocationCriterionService(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _locationCriterionService = adWordsServices.get(_session, LocationCriterionServiceInterface.class);

        return _locationCriterionService;
    }

    public CustomerSyncServiceInterface GetCustomerSyncServiceInterface(String clientId) throws IOException, ConnectionException {
        this.getSession(clientId);
        _session.setPartialFailure(true);
        AdWordsServices adWordsServices = new AdWordsServices();

        _customerSyncService = adWordsServices.get(_session, CustomerSyncServiceInterface.class);

        return _customerSyncService;
    }
}
